package org.uwrfidlab.nfc;


import java.util.List;

import org.uwrfidlab.nfc.record.ParsedNdefRecord;
import org.uwrfidlab.nfc.record.TextRecord;
import org.uwrfidlab.nfc.record.UriRecord;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.MifareUltralight;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class TagViewer extends Activity  {
	// UI Elements
	private static TextView tvTagId;
	private static TextView tvContentType;
	private static TextView tvContent;
	private static TextView tvRawMessage;
	private static TextView tvRawHexMessage;

	// NFC parts
	private static NfcAdapter mAdapter;
	private static PendingIntent mPendingIntent;
	private static IntentFilter[] mFilters;
	private static String[][] mTechLists;

	private static final String TAG = "TAG_VIEWER";
	

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.tag_viewer);

		tvTagId = (TextView) findViewById(R.id.tagId_data);
		tvContentType = (TextView) findViewById(R.id.contentType_data);
		tvContent = (TextView) findViewById(R.id.content_data);
		tvRawMessage = (TextView) findViewById(R.id.raw_msg_data);
		tvRawHexMessage = (TextView) findViewById(R.id.raw_msg_hex_data);

		
		setButtonListeners();

		mAdapter = NfcAdapter.getDefaultAdapter(this);
		
		// Create a generic PendingIntent that will be deliver to this activity.
		// The NFC stack
		// will fill in the intent with the details of the discovered tag before
		// delivering to
		// this activity.
		mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
				getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
		// Setup an intent filter for all MIME based dispatches
		IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);

		try {
			ndef.addDataType("*/*");
		} catch (MalformedMimeTypeException e) {
			throw new RuntimeException("fail", e);
		}
		//mFilters = new IntentFilter[] { ndef, };
		mFilters = null;
		// Setup a tech list for all NfcF tags
//		mTechLists = new String[][] { 
//				new String[] { MifareUltralight.class.getName() },
//				new String[] { MifareClassic.class.getName()}};
		
		mTechLists =null;

		Intent intent = getIntent();
		resolveIntent(intent);

	}


	void resolveIntent(Intent intent) {
		 // Parse the intent
        String action = intent.getAction();
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)
        		|| NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
        		|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
            // When a tag is discovered we send it to the service to be save. We
            // include a PendingIntent for the service to call back onto. This
            // will cause this activity to be restarted with onNewIntent(). At
            // that time we read it from the database and view it.
			try {
				String tagId = null;
				String contentType = null;
				String content = null;
				
				Tag myTag = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
				tagId = byteArrayToHexString(myTag.getId());
				//tagId = getHexString(myTag.getId(), myTag.getId().length);
				
				if (tagId != null) {						
					tvTagId.setText(tagId);
				}
				
	            Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
	            NdefMessage[] msgs;
	            if (rawMsgs != null) {
	                msgs = new NdefMessage[rawMsgs.length];
	                for (int i = 0; i < rawMsgs.length; i++) {
	                    msgs[i] = (NdefMessage) rawMsgs[i];
	                }
	            } else {
	                // Unknown tag type
	                byte[] empty = new byte[] {};
	                NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
	                NdefMessage msg = new NdefMessage(new NdefRecord[] {record});
	                msgs = new NdefMessage[] {msg};
	            }
	            NdefMessage msg = (NdefMessage) rawMsgs[0];
	            NdefRecord cardRecord = msg.getRecords()[0];
	            String payload = byteArrayToHexString(cardRecord.getPayload()); 
	            tvRawHexMessage.setText( payload);
	            payload=new String(cardRecord.getPayload());
	            tvRawMessage.setText( payload);
	            
	            List<ParsedNdefRecord> records = NdefMessageParser.parse(msg);
	            final int size = records.size();
	            for (int i = 0; i < size; i++) {
	                ParsedNdefRecord rcrd = records.get(0);
	                if ( rcrd.getClass() == TextRecord.class){
	                	content= ((TextRecord)rcrd).getText();
	                	contentType = "Text";
	                }
	                else if (rcrd.getClass() == UriRecord.class ){
	                	content= ((UriRecord)rcrd).getUri().toString();
	                	contentType = "Uri";
	                }
	            }
	            if (content != null) {		
	            	tvContentType.setText(contentType);
					tvContent.setText(content);
	            }

			}//end of try           
			catch (Exception e) {
				Log.e(TAG, e.getLocalizedMessage());
				//showAlert("Tag Reading Error");
			}
		} 
		else {
//			status_Data.setText("Online + Scan a tag");
		}
	}

//	//@Override
//	public void onClick(View v) {
//		clearFields();
//	}

	private static void clearFields() {
		tvTagId.setText("");
		tvContentType.setText("");
		tvContent.setText("");
		tvRawHexMessage.setText("");
		tvRawMessage.setText("");
	}

	//converts byte data to hex string
    private String byteArrayToHexString(byte[] bytes) {
    	StringBuffer hexString = new StringBuffer();
        for (byte b : bytes) {
          int intVal = b & 0xff;
          if (intVal < 0x10)
            hexString.append("0");
          hexString.append(Integer.toHexString(intVal));
        }
        return hexString.toString().toUpperCase();    
    }
    
	@Override
	public void onResume() {
		super.onResume();
		 if (mAdapter != null) {
	            if (!mAdapter.isEnabled()) {
	                //showAlert(R.string.error, R.string.nfc_disabled);
	            }
			mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters,
					mTechLists);
		}
	}

	@Override
	public void onNewIntent(Intent intent) {
		Log.i("Foreground dispatch", "Discovered tag with intent: " + intent);
		setIntent(intent);
		resolveIntent(intent);
	}

	@Override
	public void onPause() {
		super.onPause();
		mAdapter.disableForegroundDispatch(this);
	}

	private void setButtonListeners() {

		Button btnClear = (Button) findViewById(R.id.btn_clear);
		// Register the onClick listener with the implementation above
		btnClear.setOnClickListener( new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				clearFields();
			}
		});
		
		Button btnBack = (Button) findViewById(R.id.btn_back);
		// Register the onClick listener with the implementation above
		btnBack.setOnClickListener( new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				finish();
			}
		});
		
	}
}
